package com.ficus.road.maintain.client;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ficus.road.maintain.client.Response.*;
import com.ficus.road.maintain.client.Response.CameraInformationResponse.*;
import com.ficus.road.maintain.core.model.*;
import com.ficus.road.maintain.dao.HitDao;
import com.ficus.road.maintain.operationlog.annotation.OpLog;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.time.LocalDate;
import java.util.*;


import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.util.Base64;

/**
 * 城道中心接口
 * jingyan.ma
 * 2023/08/11 下午17：54
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class XljVideoClient {

    @Value("${xlj.user-name}")
    private String userName;
    @Value("${xlj.pass-word}")
    private String passWord;
    @Value("${xlj.server}")
    private String server;
    @Value("${xlj.RSA-encipher}")
    private String encipher;
    private final RestTemplate restTemplate;

    @Autowired
    HitDao hitDao;

    /**
     * 登录
     *
     * @return
     * @throws JsonProcessingException
     */
    public String LogIn() throws JsonProcessingException {
        String url = server + "/user/login";
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("userName", userName);
        //对密码进行RSA加密
        params.add("password", RSAEncipher(passWord));

        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        // 创建一个表单请求对象
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);

        // 发送 POST 请求并获取响应
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, JsonNode.class);
        System.out.println("===============================");
        System.out.println(JSONObject.toJSONString(responseEntity));
        return responseEntity.getHeaders().get("Set-Cookie").get(0);
    }

    /**
     * RSA加密
     *
     * @throws JsonProcessingException
     */
    public String RSAEncipher(String passWord) throws JsonProcessingException {
        // 替换YOUR_PUBLIC_KEY为实际的RSA公钥
        String publicKeyString = encipher;
        // 将Base64编码的公钥字符串解码为字节数组
        byte[] encodedPublicKey = Base64.getDecoder().decode(publicKeyString);
        // 创建RSA公钥对象
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedPublicKey);
        KeyFactory keyFactory = null;
        try {
            keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            // 加密字符串
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedBytes = cipher.doFinal(passWord.getBytes());
            return bytesToHex(encryptedBytes);
//            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (NoSuchAlgorithmException | InvalidKeyException | BadPaddingException | InvalidKeySpecException |
                IllegalBlockSizeException | NoSuchPaddingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 字节数组转成16进制字符串
     *
     * @param bytes
     * @return
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }

    /**
     * 获取下立交摄像头信息
     *
     * @throws IOException
     */
    public List<CameraInformation> GetCameraInformation(String XljId, String cookie) throws JsonProcessingException {
        String url = server + "/XljCamera?XljId=" + XljId;
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return null;
        }


        ObjectMapper objectMapper = new ObjectMapper();
        CameraInformationResponse cameraInformationResponse = objectMapper.treeToValue(reponseBody, CameraInformationResponse.class);
        return cameraInformationResponse.getData();
    }

    /**
     * 获取摄像头的视频地址
     *
     * @throws IOException
     */
    public VideoAddressResponse.VideoInformation GetVideoAddress(String cameraId, String channelId, String cookie) throws JsonProcessingException {
        String url = server + "/XljCamera/address?cameraId=" + cameraId + "&channelId=" + channelId;
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return null;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        VideoAddressResponse videoAddressResponse = objectMapper.treeToValue(reponseBody, VideoAddressResponse.class);
        return videoAddressResponse.getData();
    }

    /**
     * 通过时间获取标段分数(默认当前时间)
     *
     * @return
     * @throws JsonProcessingException
     */
    public SectionScoreResponse GetSectionScoreByTime(String cookie, LocalDate date) throws JsonProcessingException {

        String url = server + "/comprehensiveScore?date=" + date;
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return null;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.treeToValue(reponseBody, SectionScoreResponse.class);
    }

    /**
     * 通过unid获取分数详情
     *
     * @param unid
     * @return
     * @throws JsonProcessingException
     */
    public ScoreDetailsResponse GetScoreDetailsByUnid(String unid, String cookie) throws JsonProcessingException {
        String url = server + "/comprehensiveScore/detail?unid=" + unid;
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return null;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        ScoreDetailsResponse scoreDetailsResponse = objectMapper.treeToValue(reponseBody, ScoreDetailsResponse.class);
        List<Details> data = scoreDetailsResponse.getData();
        for (Details datum : data) {
            List<Children> children = datum.getChildren();
            for (Children child : children) {
                // 因为会有重复的扣分项，所以使用set集合收集
                HashSet<String> strings = new HashSet<>();
                String deductScoreReason = child.getDeductScoreReason();
                // 去获取扣分详情
                strings.addAll(GetdeductScoreReason(child.getDetailUnid(), cookie));
                if (deductScoreReason != null) {
                    strings.add(deductScoreReason);
                }
                // 将set集合转成String赋值到扣分详情字段上
                String replace = strings.toString().replace("[", "").replace("]", "");
                child.setDeductScoreReason(replace);
            }
        }
        return scoreDetailsResponse;
    }

    /**
     * 通过detailUnid获取扣分详情
     *
     * @param detailUnid
     * @return
     * @throws JsonProcessingException
     */
    public HashSet<String> GetdeductScoreReason(String detailUnid, String cookie) throws JsonProcessingException {
        String url = server + "/comprehensiveScore/deduction-detail?detailUnid=" + detailUnid;
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return null;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        ScoreDetailsResponse scoreDetailsResponse = objectMapper.treeToValue(reponseBody, ScoreDetailsResponse.class);
        // 因为会有重复的扣分项，所以使用set集合收集
        HashSet<String> strings = new HashSet<>();
        for (Details datum : scoreDetailsResponse.getData()) {
            strings.add(datum.getDeductScoreReason());
        }
        return strings;
    }


    /**
     * 城市道路工单处置详情
     */
    @OpLog(description = "推送中海城道工单")
    public void urbanRoadClient(String cookie) throws JsonProcessingException {
        //获取前两天处置详情
        LocalDate localDate = LocalDate.now().minusDays(10);
        LocalDate now = LocalDate.now();
        String url = server + "/complainData?startTime=" + localDate + "&endTime=" + now + "&typeFlag=3";
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        // 调用城道接口获取称道处置详情
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        UrbanRoad urbanRoads = objectMapper.treeToValue(reponseBody, UrbanRoad.class);
        // 找到对应病害并修改
        for (UrbanRoadData urbanRoad : urbanRoads.getData()) {
            Hit hit = hitDao.findOne(new Query(Criteria.where("_id").is(urbanRoad.getCrackData().getSid())));
            if (hit != null) {
                // 新建病害处置信息
                HistoryHit historyHit = getHistoryHit(urbanRoad, hit);
                //TODO:修改病害历史
                List<HistoryHit> list = hit.getList();
                HitStatusEnum status = historyHit.getAttrs().getStatus();
                HitStatusEnum hitStatusEnum = hit.getAttrs().getStatus();
                //如果新数据以上次保存的数据一致，则取消保存
                //如果老数据为已复核，则取消保存
                boolean updateHit = !hitStatusEnum.equals(status) && !hitStatusEnum.equals(HitStatusEnum.CONFIRMED);
                if (updateHit) {
                    list.add(0, historyHit);
                    // 修改病害信息
                    Update update = new Update().set("list", list).set("attrs.status", status);
//                    hitDao.update(hit.getId(), update);
                }
            } else {
                log.info("无此病害" + urbanRoad.getCrackData().getSid());
            }
        }
    }

    /**
     * 新建病害新历史
     *
     * @param urbanRoad
     * @param hit
     * @return
     */
    public HistoryHit getHistoryHit(UrbanRoadData urbanRoad, Hit hit) {
        UrbanRoadData.CrackData crackData = urbanRoad.getCrackData();
        HistoryHit historyHit = new HistoryHit();
        HistoryHitAttrs historyHitAttrs = new HistoryHitAttrs();
        // 赋值gps
        historyHitAttrs.setGpsLocation(new GpsLocation(crackData.getLgt(), crackData.getLat()));
        // 赋值处置状态
        switch (urbanRoad.getFlowType()) {
            case "1":
                historyHitAttrs.setStatus(HitStatusEnum.NOTED);
                break;
            case "2":
                historyHitAttrs.setStatus(HitStatusEnum.COMPLETE);
                break;
            case "3":
                historyHitAttrs.setStatus(HitStatusEnum.CONFIRMED);
                break;
        }
        // 赋值设备id
        historyHitAttrs.setCarId(crackData.getDeviceId());
        // 赋值场景图
        historyHitAttrs.setSceneImage(crackData.getPicUrl());
        // 赋值问题描述
        historyHitAttrs.setDescription(urbanRoad.getEventDescription());
        // 赋值开始处置时间
        if (urbanRoad.getDealingTime() != null) {
            try {
                long timestamp = urbanRoad.getDealingTime().getTime() / 1000; // 转换为秒级时间戳
                historyHitAttrs.setStartHandleTime(timestamp);
            } catch (Exception e) {
                // 日期解析错误
                historyHitAttrs.setStartHandleTime(0L);
            }
        }
        // 赋值结束处置时间
        if (urbanRoad.getLastUpdateTime() != null) {
            try {
                long timestamp = urbanRoad.getLastUpdateTime().getTime() / 1000; // 转换为秒级时间戳
                historyHitAttrs.setFinishHandleTime(timestamp);
            } catch (Exception e) {
                // 日期解析错误
                historyHitAttrs.setFinishHandleTime(0L);
            }
        }
        // 赋值事件发现时间
        historyHit.setHitTime(hit.getHitTime());
        // 赋值道路状态
        historyHit.setRoadType(hit.getRoadType());
        // 赋值病害信息
        historyHit.setType(hit.getType());
        // 赋值病害属性
        historyHit.setAttrs(historyHitAttrs);
        return historyHit;
    }

    /**
     * 获取城市道路GPS
     *
     * @param cookie
     * @throws JsonProcessingException
     */
    public void GetUrbanRoadGps(String cookie) throws JsonProcessingException {
        String url = server + "/roadCenter";
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        UrbanRoadGps urbanRoadGps = objectMapper.treeToValue(reponseBody, UrbanRoadGps.class);
        System.out.println("获取道路Gps结束");
    }

    public void testUrbanRoadClient(String cookie) throws JsonProcessingException {
        //获取前两天处置详情
        LocalDate localDate = LocalDate.now().minusDays(10);
        LocalDate now = LocalDate.now();
        String url = server + "/complainData?startTime=" + localDate + "&endTime=" + now + "&typeFlag=3";
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        // 调用城道接口获取称道处置详情
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return;
        }
    }


    public JsonNode getComplainData(String cookie, String yearMonth) {

        String url = server + "/cdzxinterface/complainTaskInfo?yearMonth=" + yearMonth;
        HttpHeaders headers = new HttpHeaders();
        cookie = cookie.substring(0, cookie.indexOf(";"));
        System.out.println("Cookie:" + cookie);
        headers.set("Cookie", cookie);

        headers.setContentType(MediaType.APPLICATION_JSON);  // 设置请求头的 Content-Type 为 application/json

        // 构造请求体（例如发送一些 JSON 数据）
        // 这里假设你要发送一个简单的 JSON 对象，可以根据实际需求修改
        String jsonRequestBody = "{\"yearMonth\":\""+yearMonth+"\"}";

        // 如果你想传送 JsonNode 类型的请求体，也可以将它序列化为字符串
        // JsonNode jsonRequestBody = ... // 用你自己的 JSON 数据构建 JsonNode 对象

        HttpEntity<String> requestEntity = new HttpEntity<>(jsonRequestBody, headers);  // 使用 String 类型的 JSON 请求体

        // 调用接口并获取响应
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, JsonNode.class);

        // 获取响应体
        JsonNode responseBody = responseEntity.getBody();

        if (Objects.isNull(responseBody)) {
            return null;
        }
        return responseBody;
    }


    public JsonNode getComplainData1(String cookie, String yearMonth) {

        String url = server + "/cdzxinterface/complainTaskInfo?yearMonth=" + yearMonth;
        HttpHeaders headers = new HttpHeaders();
        cookie = cookie.substring(0, cookie.indexOf(";"));
        cookie=cookie.substring(cookie.indexOf("=")+1);
        System.out.println("Cookie:" + cookie);
        headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        // 调用城道接口获取称道处置详情
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return null;
        }
        return reponseBody;
    }


    public JsonNode getComplainData2(String cookie, String yearMonth) {

        String url = server + "/cdzxinterface/complainTaskInfo?yearMonth=" + yearMonth;
        HttpHeaders headers = new HttpHeaders();
        cookie = cookie.substring(0, cookie.indexOf(";"));
        cookie=cookie.substring(cookie.indexOf("=")+1);
        System.out.println("Cookie:" + cookie);
   //     headers.set("Cookie", cookie);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(headers);
        // 调用城道接口获取称道处置详情
        ResponseEntity<JsonNode> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, JsonNode.class);
        JsonNode reponseBody = responseEntity.getBody();
        if (Objects.isNull(reponseBody)) {
            return null;
        }
        return reponseBody;
    }


}
